package com.vmware2.vim25.mo.samples.vm;

import com.vmware.vim25.*;
import com.vmware.vim25.mo.*;
import lombok.extern.slf4j.Slf4j;

import java.net.MalformedURLException;
import java.net.URL;
import java.rmi.RemoteException;

@Slf4j
public class CreateVM {


  public static void main(String[] args) throws RemoteException {
    // 定义DataCenter数据中心名称
    String dcName = "Datacenter";
    // 定义虚拟机名称
    String vmName = "zs-test-vm-04";
    // 内存大小
    long memorySizeMB = 1024*2;
    // CPU核心数
    int cupCount = 1;
    String guestOsId = "ubuntu64Guest";
    long diskSizeKB = 1024*1024*16;
    String diskMode = "persistent";
    String datastoreName = "datastore10";
    // 网络适配器
    String netName = "VM Network";
    // 网卡名称
    String nicName = "Network Adapter 1";

    String url = "https://192.168.157.2:443/sdk";
    String userName = "administrator@vsphere.local";
    String passWord = "Admin@123";

    URL uri = null;
    try {
          uri = new URL(url);
    } catch (MalformedURLException e) {
          e.printStackTrace();
    }
    ServiceInstance si = null;
      try {
          si = new ServiceInstance(uri, userName, passWord, true);
      } catch (RemoteException e) {
          e.printStackTrace();
      } catch (MalformedURLException e) {
          e.printStackTrace();
      }
      Folder rootFolder = si.getRootFolder();
      Datacenter dc = null;
      try {
          dc = (Datacenter) new InventoryNavigator(rootFolder).searchManagedEntity("Datacenter", dcName);
      } catch (RemoteException e) {
          e.printStackTrace();
      }
      ResourcePool rp = null;
      try {
          rp = (ResourcePool) new InventoryNavigator(dc).searchManagedEntities("ResourcePool")[0];
      } catch (RemoteException e) {
          e.printStackTrace();
      }

      Folder vmFolder = null;
      try {
          vmFolder = dc.getVmFolder();
      } catch (RemoteException e) {
          e.printStackTrace();
      }
    VirtualMachineConfigSpec vmSpec = new VirtualMachineConfigSpec();
    vmSpec.setName(vmName);
    vmSpec.setAnnotation("测试VirtualMachine");
    vmSpec.setMemoryMB(memorySizeMB);
    vmSpec.setNumCPUs(cupCount);
    vmSpec.setGuestId(guestOsId);

    // create virtual devices
    int cKey = 1000;
    VirtualDeviceConfigSpec scsiSpec = createScsiSpec(cKey);
    // 磁盘配置
    VirtualDeviceConfigSpec diskSpec = createDiskSpec(datastoreName, cKey, diskSizeKB, diskMode);
    // 网卡
    VirtualDeviceConfigSpec nicSpec = null;
    try {
       nicSpec = createNicSpec(netName, nicName);
    } catch (Exception e) {
       e.printStackTrace();
    }
    vmSpec.setDeviceChange(new VirtualDeviceConfigSpec[]{scsiSpec, diskSpec, nicSpec});
    VirtualMachineFileInfo vmfi = new VirtualMachineFileInfo();
    vmfi.setVmPathName("["+ datastoreName +"]");
    vmSpec.setFiles(vmfi);
    Task task = null;
      try {
          task = vmFolder.createVM_Task(vmSpec,rp,null);
          //VirtualMachineConfigSpec config, ResourcePool pool, HostSystem host
          VirtualMachineConfigSpec configSpec = new VirtualMachineConfigSpec();
          //HostSystem hostSystem = new HostSystem();
          //ResourcePool pool = new ResourcePool();
          //vmFolder.createVM_Task();
      } catch (RemoteException e) {
          e.printStackTrace();
      }
      String result = null;
//      try {
//          result = task.waitForMe();
//      } catch (RemoteException e) {
//          e.printStackTrace();
//      }
      try {
          result = task.waitForTask();

      } catch (RemoteException e) {
          e.printStackTrace();
      } catch (InterruptedException e) {
          e.printStackTrace();
      }
      if(result == Task.SUCCESS) {
          System.out.println("VM Created Sucessfully");
          System.out.println(task.getTaskInfo().getEntityName());
      } else {
          System.out.println("VM could not be created. ");
      }
  }

    /**
     * 创建
     * @param cKey
     * @return
     */
  static VirtualDeviceConfigSpec createScsiSpec(int cKey) {
    VirtualDeviceConfigSpec scsiSpec = new VirtualDeviceConfigSpec();
    scsiSpec.setOperation(VirtualDeviceConfigSpecOperation.add);
    VirtualLsiLogicController scsiCtrl = new VirtualLsiLogicController();
    scsiCtrl.setKey(cKey);
    scsiCtrl.setBusNumber(0);
    scsiCtrl.setSharedBus(VirtualSCSISharing.noSharing);
    scsiSpec.setDevice(scsiCtrl);
    return scsiSpec;
  }

    /**
     * 创建磁盘
     * @param dsName
     * @param cKey
     * @param diskSizeKB
     * @param diskMode
     * @return
     */
  static VirtualDeviceConfigSpec createDiskSpec(String dsName, int cKey, long diskSizeKB, String diskMode) {
    VirtualDeviceConfigSpec diskSpec = new VirtualDeviceConfigSpec();
    diskSpec.setOperation(VirtualDeviceConfigSpecOperation.add);
    diskSpec.setFileOperation(VirtualDeviceConfigSpecFileOperation.create);
    VirtualDisk vd = new VirtualDisk();
    vd.setCapacityInKB(diskSizeKB);
    diskSpec.setDevice(vd);
    vd.setKey(0);
    vd.setUnitNumber(0);
    vd.setControllerKey(cKey);
    VirtualDiskFlatVer2BackingInfo diskfileBacking = new VirtualDiskFlatVer2BackingInfo();
    String fileName = "["+ dsName +"]";
    diskfileBacking.setFileName(fileName);
    diskfileBacking.setDiskMode(diskMode);
    diskfileBacking.setThinProvisioned(true);
    vd.setBacking(diskfileBacking);
    return diskSpec;
  }

    /**
     * 创建网卡
     * @param netName
     * @param nicName
     * @return
     */
  static VirtualDeviceConfigSpec createNicSpec(String netName,String nicName) {
    VirtualDeviceConfigSpec nicSpec = new VirtualDeviceConfigSpec();
    nicSpec.setOperation(VirtualDeviceConfigSpecOperation.add);
    VirtualEthernetCard nic =  new VirtualPCNet32();
    VirtualEthernetCardNetworkBackingInfo nicBacking = 
        new VirtualEthernetCardNetworkBackingInfo();
    nicBacking.setDeviceName(netName);
    Description info = new Description();
    info.setLabel(nicName);
    info.setSummary(netName);
    nic.setDeviceInfo(info);

    nic.setAddressType("generated");
    nic.setBacking(nicBacking);
    nic.setKey(0);
   
    nicSpec.setDevice(nic);
    return nicSpec;
  }
}